package net.gdface.cassdk;

import android.renderscript.ScriptIntrinsicYuvToRGB;
import android.support.test.runner.AndroidJUnit4;

import static net.gdface.utils.SampleLog.log;
import static org.junit.Assert.*;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import net.gdface.exception.ServiceRuntimeException;
import net.gdface.image.ImageErrorException;
import net.gdface.sdk.CodeInfo;
import net.gdface.sdk.FaceApiGenericDecorator;
import net.gdface.sdk.NotFaceDetectedException;

import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
/**
 * {@link net.gdface.sdk.FaceApi}测试
 * @author guyadong
 *
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RunWith(AndroidJUnit4.class)
public class FaceApiTest {
	private static final Logger logger = LoggerFactory.getLogger(FaceApiTest.class);

	private static FaceApiGenericDecorator faceapi;

	static private CodeInfo[] codes;
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		faceapi= new FaceApiGenericDecorator(FaceApiCasAndroid.getInstance());
	}
	@Test
	public final void test1DetectFaces() throws ImageErrorException, IllegalArgumentException, NotFaceDetectedException, MalformedURLException,
			IOException {
		try{
			CodeInfo[] codes = faceapi.detectFace(FaceApiTest.class.getResourceAsStream("/images/he049.jpg"));
			for(CodeInfo c:codes){
				logger.info("FRECT={}",c.getPos());
			}
		}catch(RuntimeException e){
			if(e.getCause() instanceof ServiceRuntimeException){
				((ServiceRuntimeException)e.getCause()).printServerStackTrace();
			}else{
				e.printStackTrace();
			}
		}
	}
	@Test
	public final void test2DetectFace() throws ImageErrorException, IllegalArgumentException, NotFaceDetectedException, MalformedURLException,
			IOException {
		try{
			URL img = FaceApiTest.class.getResource("/images/guyadong-1.jpg");
			codes = faceapi.detectFace(img);
			for(CodeInfo c:codes){
				logger.info("FRECT={}",c.getPos());
			}
		}catch(RuntimeException e){
			if(e.getCause() instanceof ServiceRuntimeException){
				((ServiceRuntimeException)e.getCause()).printServerStackTrace();
			}else{
				e.printStackTrace();
			}
		}
	}
	@Test
	public final void test3GetCodeInfo() throws ImageErrorException, IllegalArgumentException, NotFaceDetectedException, MalformedURLException,
			IOException {
		try{
			URL img = FaceApiTest.class.getResource("/images/guyadong-1.jpg");
			faceapi.getCodeInfo(img, 0, codes);
			for(CodeInfo c:codes){
				logger.info("CodeInfo={}",c);
			}
		}catch(RuntimeException e){
			if(e.getCause() instanceof ServiceRuntimeException){
				((ServiceRuntimeException)e.getCause()).printServerStackTrace();
			}else{
				e.printStackTrace();
			}
		}
	}
	@Test
	public final void test4DetectAndGetCodeInfo() throws ImageErrorException, NotFaceDetectedException,
			IOException {
		try{
			//CodeInfo[] codes = faceapi.detectAndGetCodeInfo(TestFaceAPI.class.getResourceAsStream("/images/guyadong-1.jpg"), 0,null);
			CodeInfo[] codes = faceapi.detectAndGetCodeInfo(FaceApiTest.class.getResourceAsStream("/images/74ddfc06d1e83d1e669947e7243cf75e.png"), 0);
			for(CodeInfo c:codes){
				logger.info("CodeInfo={}",c);
			}
		}catch(RuntimeException e){
			if(e.getCause() instanceof ServiceRuntimeException){
				((ServiceRuntimeException)e.getCause()).printServerStackTrace();
			}else{
				e.printStackTrace();
			}
		}finally{
		}
	}
	@Test
	public final void test5DetectAndCompare2Face() throws ImageErrorException, NotFaceDetectedException, IOException{
		try{
			{
				double sim = faceapi.detectAndCompare2Face(
						FaceApiTest.class.getResourceAsStream("/images/guyadong-1.jpg"), 
						null,
						FaceApiTest.class.getResourceAsStream("/images/guyadong-2.jpg"), 
						null);
				logger.info("similarity={}",sim);
			}
			{
				CodeInfo code1 = faceapi.detectAndGetCodeInfo(FaceApiTest.class.getResourceAsStream("/images/guyadong-1.jpg"), 1)[0];
				Map<CodeInfo, Double> result = faceapi.compareFaces(code1.getCode(), FaceApiTest.class.getResourceAsStream("/images/he049.jpg"), 0);
				int count = 0;
				for( Entry<CodeInfo, Double> entry:result.entrySet()){
					log("entry {} simility: {}  {}",++count,entry.getValue(),entry.getKey().getPos());
				}
			}
		}catch(RuntimeException e){
			if(e.getCause() instanceof ServiceRuntimeException){
				((ServiceRuntimeException)e.getCause()).printServerStackTrace();
			}else{
				e.printStackTrace();
			}
		}
	}
	@Test
	public final void test6HashFace() throws ImageErrorException, IOException{
		try{
			boolean hasFace = faceapi.hasFace(
					FaceApiTest.class.getResourceAsStream("/images/timg01.jpg"));
			logger.info("hasFace={}",hasFace);
			assertFalse(hasFace);
			boolean hasFace2 = faceapi.hasFace(
					FaceApiTest.class.getResourceAsStream("/images/guyadong-1.jpg"));
			logger.info("hasFace={}",hasFace2);
			assertTrue(hasFace2);
		}catch(RuntimeException e){
			if(e.getCause() instanceof ServiceRuntimeException){
				((ServiceRuntimeException)e.getCause()).printServerStackTrace();
			}else{
				e.printStackTrace();
			}
		}
	}
	/**
	 * 多线程测试
	 * @throws InterruptedException
	 */
	@Test
	public void test7MultiThreadDetectFace() throws InterruptedException{
        ExecutorService executor = new ThreadPoolExecutor(
                2,
                2,
                0,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(),
                new ThreadFactoryBuilder()
                    .setNameFormat("cached-pool-%d")
                    .build());
		final String[] images = new String[]{
				"/images/guyadong-1.jpg",
				"/images/guyadong-2.jpg",
				"/images/guyadong-3.jpg",
				"/images/guyadong-4.jpg"};
		for(int i=0;i<200;++i){
			final String f = images[i%4];
			executor.execute(new Runnable(){
				@Override
				public void run() {
					try {
						CodeInfo[] codes = faceapi.detectAndGetCodeInfo(FaceApiTest.class.getResourceAsStream(f), 0);
						for(CodeInfo c:codes){
							logger.info("CodeInfo={}",c);
						}
					} catch (Exception e) {
						e.printStackTrace();
					} 
				}});
		}
		executor.shutdown();
		while(!executor.isTerminated()){
			executor.awaitTermination(10, TimeUnit.SECONDS);
		}
	}
}
